package com.opengit;

import com.sun.media.imageio.plugins.tiff.TIFFTag;
import com.sun.media.jai.codec.*;
import com.sun.media.jai.codecimpl.TIFFImageEncoder;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: yxf
 * @version: 1.0
 * @Date: 2019/01/30 10:10
 * @Description: 利用JAI类库将图片合并为TIFF格式
 */
public class TiffExportJAI {
    /**
     * TIFFField[]
     */
    private static final TIFFField[] TIFF_EXP_EXTRAS = new TIFFField[]{
            new TIFFField(262, TIFFField.TIFF_SHORT, 1, (Object) new short[]{6}),
            new TIFFField(282, TIFFField.TIFF_RATIONAL, 1, (Object) new long[][]{{(long) 200, 1}, {0, 0}}),
            new TIFFField(283, TIFFField.TIFF_RATIONAL, 1, (Object) new long[][]{{(long) 200, 1}, {0, 0}}),
            new TIFFField(258, TIFFField.TIFF_SHORT, 1, (Object) new char[]{8})
    };

    /**
     * 压缩参数
     *
     * @return : TIFFEncodeParam对象
     */
    private static TIFFEncodeParam getTIFFEncodeParam() {
        TIFFEncodeParam param = new TIFFEncodeParam();
        JPEGEncodeParam paramJpeg = new JPEGEncodeParam();
        paramJpeg.setQuality(0.75f);
        paramJpeg.setWriteImageOnly(true);
        param.setJPEGEncodeParam(paramJpeg);
        param.setCompression(TIFFEncodeParam.COMPRESSION_JPEG_TTN2);
        param.setJPEGCompressRGBToYCbCr(false);
        param.setWriteTiled(true);
        param.setTileSize(512, 512);
        param.setReverseFillOrder(false);
        param.setExtraFields(TIFF_EXP_EXTRAS);
        param.setDeflateLevel(6);
        return param;
    }


    /**
     * 多个文件转TIFF
     *
     * @param filePaths    : 文件列表
     * @param targetPath   : 目标路径
     * @param distFileName : 目标文件名
     */
    public static void many2one(List<String> filePaths, String targetPath, String distFileName) {
        if (filePaths != null && filePaths.size() > 0) {
            try {
                int fileCount = filePaths.size();
                ArrayList pages = new ArrayList(fileCount);
                PlanarImage firstPage = null;
                PlanarImage page;
                File file;
                FileSeekableStream fileSeekableStream = null;
                for (int i = 0; i < fileCount; i++) {
                    file = new File(filePaths.get(i));
                    fileSeekableStream = new FileSeekableStream(file.getCanonicalPath());
                    if (i == 0) {
                        firstPage = JAI.create("stream", fileSeekableStream);
                    } else {
                        page = JAI.create("stream", fileSeekableStream);
                        pages.add(page);
                    }
                }

                TIFFEncodeParam param = getTIFFEncodeParam();
                param.setExtraImages(pages.iterator());

                file = new File(targetPath);
                if (!file.exists()) {
                    file.mkdirs();
                }

                OutputStream os = new FileOutputStream(targetPath + File.separator + distFileName);
                ImageEncoder enc = ImageCodec.createImageEncoder("tiff", os, param);
                enc.encode(firstPage);
                os.flush();
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
